<template>
  <div class="ports-status-box">
    <el-row class="ports-status" align="middle">
      <el-col :span="5">
        <span class="ports-title">{{ $t('portsStatus') }}：</span>
        <span :class="isPortsStatus">
          {{ portStatusText }}
        </span>
      </el-col>
      <el-col :span="19">
        <div class="flex align-center ports-select">
          <div class="flex align-center">
            <span class="ports-title">串口：</span>
            <el-select
              v-model="currentSerialPort"
              class="ports-select-box"
              suffix-icon="CaretBottom"
              style="width: 110px"
              :disabled="portsStatus === 2"
            >
              <el-option
                v-for="(item, index) in serialPortList"
                :key="index"
                :label="item.path"
                :value="item.path"
              />
            </el-select>
          </div>
          <div class="flex align-center margin-left-xs">
            <span class="ports-title">波特率：</span>
            <el-select
              class="ports-select-box"
              v-model="currentBaud"
              filterable
              suffix-icon="CaretBottom"
              style="width: 110px"
              :disabled="portsStatus === 2"
            >
              <el-option
                v-for="(item, index) in baudRateList"
                :key="index"
                :label="item.dictLabel"
                :value="+item.dictLabel"
              >
              </el-option>
            </el-select>
          </div>
          <template v-if="!isUart">
            <div class="flex align-center margin-left-xs">
              <span class="ports-title">CAN波特率：</span>
              <el-select
                class="ports-select-box"
                v-model="canRate"
                filterable
                suffix-icon="CaretBottom"
                style="width: 110px"
                :disabled="portsStatus === 2"
              >
                <el-option
                  v-for="(value, key) in canRateList"
                  :label="value"
                  :value="+key"
                  :key="key"
                >
                </el-option>
              </el-select>
            </div>
            <div class="flex align-center margin-left-xs">
              <el-select
                class="ports-select-box"
                v-model="msgType"
                filterable
                suffix-icon="CaretBottom"
                style="width: 110px"
                :disabled="portsStatus === 2"
              >
                <el-option
                  v-for="(value, key) in msgTypeList"
                  :label="value"
                  :value="+key"
                  :key="key"
                >
                </el-option>
              </el-select>
            </div>
          </template>
          <el-button class="open-port" type="primary" @click="openSerialPort">
            {{ portsStatus === 0 ? $t('open') : $t('close') }}
          </el-button>
          <el-button
            class="open-port"
            type="primary"
            :disabled="modelOnlineStatus === 1"
            @click="handleSetUartOrCan"
          >
            {{ isUart ? 'CAN' : '通用' }}
          </el-button>
        </div>
      </el-col>
    </el-row>
    <slot name="footer"></slot>
  </div>
</template>

<script lang='ts' setup>
import { computed, onUnmounted, ref, watch } from 'vue'
import { usePortsStore } from '@renderer/stores/portsStore'
import { storeToRefs } from 'pinia'
import { useMessage } from '@renderer/hooks/message'
import { useI18n } from 'vue-i18n'

const messageTip = useMessage()
const { t } = useI18n()
const portsStore = usePortsStore()

const {
  currentSerialPort,
  serialPortList,
  portsStatus,
  currentBaud,
  canHeartBeatTimer,
  isUart,
  modelOnlineStatus
} = storeToRefs(portsStore)

const baudRateList = [
  {
    dictLabel: '1200',
    dictValue: 0x01
  },
  {
    dictLabel: '2400',
    dictValue: 0x02
  },
  {
    dictLabel: '4800',
    dictValue: 0x03
  },
  {
    dictLabel: '9600',
    dictValue: 0x04
  },
  {
    dictLabel: '14400',
    dictValue: 0x05
  },
  {
    dictLabel: '19200',
    dictValue: 0x06
  },
  {
    dictLabel: '38400',
    dictValue: 0x07
  },
  {
    dictLabel: '43000',
    dictValue: 0x08
  },
  {
    dictLabel: '57600',
    dictValue: 0x09
  },
  {
    dictLabel: '76800',
    dictValue: 0x0a
  },
  {
    dictLabel: '115200',
    dictValue: 0x0b
  },
  {
    dictLabel: '128000',
    dictValue: 0x0c
  }
]

// CAN 波特率
const canRateList = {
  0: '100',
  1: '125',
  2: '150',
  3: '200',
  4: '250',
  5: '300',
  6: '400',
  7: '500',
  8: '600',
  9: '900'
}

const msgTypeList = {
  0: '标准帧',
  1: '扩展帧'
}

// CAN 波特率
const canRate = ref(7)
// 帧类型
const msgType = ref(0)

// 获取串口列表
portsStore.getSerialPorts()

// 打开、关闭串口
const openSerialPort = () => {
  if (!currentSerialPort.value) {
    messageTip.warning(t('selectPort'))
    return
  }

  handlePort()
}

const handlePort = async () => {
  portsStore.handleSerialPort()

  if (isUart.value) {
    portsStore.writeMsg(portsStore.cmd3aSum(0xab, [0x01, 0x01, 0x00]))
  } else {
    await setConfigUsbCanRate()

    const CMD_ADDRESS = 0x01 // 心跳
    canHeartBeatTimer.value = setInterval(() => {
      portsStore.writeMsg(portsStore.cmd3aSum(CMD_ADDRESS, [0x01]))
    }, 200)
  }
}

let canTimer: any = null
const setConfigUsbCanRate = () => {
  return new Promise((resolve, reject) => {
    const CMD_ADDRESS = 0xff
    portsStore.writeMsg(portsStore.cmd3aSum(CMD_ADDRESS, [canRate.value, msgType.value]))
    portsStore.onDataReceived = (dataHex) => {
      if (dataHex[2] === CMD_ADDRESS) {
        if (dataHex[4] !== 0) {
          resolve(true)
        }
      }
    }
  })
}

const portTimer = setInterval(() => {
  portsStore.getSerialPorts()
}, 1000)

// 通用、CAN 的方式切换
const handleSetUartOrCan = () => {
  isUart.value = !isUart.value

  if (isUart.value) {
    currentBaud.value = 9600
  } else {
    currentBaud.value = 115200
  }
}

const isPortsStatus = computed(() => {
  const portStatusColor = {
    0: 'wait-status',
    1: 'timeout-status',
    2: 'success-status '
  }
  return portStatusColor[portsStatus.value]
})

const portStatusText = computed(() => {
  const portText = {
    0: t('waitConnect'),
    1: t('Connecting'),
    2: t('Connected')
  }

  return portText[portsStatus.value]
})

watch(
  () => portsStatus.value,
  (val) => {
    if (val !== 2) {
      clearInterval(canTimer)
      clearInterval(canHeartBeatTimer.value)
    }
  },
  {
    immediate: true
  }
)

onUnmounted(() => {
  clearInterval(portTimer)
  clearInterval(canTimer)
})
</script>

<style lang='scss' scoped>
.ports-status-box {
  box-sizing: border-box;
  background: $default-bg-color;
  border-radius: $boxRadius;
  padding: 20px;
  display: grid;
  row-gap: 31px;

  .open-port {
    width: 76px;
    height: 27px;
    line-height: 27px;
    background: #2697ff;
    border-radius: 6px;
    margin-left: 10px;
  }
}
</style>